/*  File Name	: EnginePlayer.cpp
 *  Author		: Javie Pong
 *	 E-mail		: 823960168@qq.com
 *  Created on	: 2012-7-1
 *  Description:
 */

#include "EnginePlayer.h"
#include "EngineMonitor.h"
#include "MySqlDB.h"

void Operation::reset()
{
	bring_chips=false;
	start = false;
	bet = false;
	raise = false;
	call = false;
	check = false;
	all_in = false;
	fold = false;
}
/////////////////////////////////////////

EnginePlayer::EnginePlayer(int p)
{
	this->reset();
}

EnginePlayer::~EnginePlayer()
{
}

void EnginePlayer::reset(void)
{
	monitor_ = NULL;
	//base_info_.reset();
	gate_id_ = 0;
	this->db_info_.reset();
	this->exit_table_reset();
}

void EnginePlayer::exit_table_reset(void)
{
	cur_table_ = NULL;
	game_status_ = GAME_STATUS_STOP;
	game_step_ =NONE_STEP;
	is_wait_ = true;
	auto_bring_in_ =false;
	notify_bring_chips_ = false;
	notify_start_ = false;
	cur_bet_chips_  = 0;
	chips_in_table_ = 0;
	last_bring_chips_ = 0;
	//cur_use_chips_  = 0;
	win_chips_ = 0;
	table_index_ = -1;
	card_[0]= NULL;
	card_[1]= NULL;
}

const DBInfo &EnginePlayer::dbinfo(void)
{
	return this->db_info_;
}

MySqlDB *EnginePlayer::globaldb(void)
{
	return this->monitor()->find_db(this);
}

void EnginePlayer::stop_game_reset(void)
{
	//game_status_ = GAME_STATUS_STOP;
	cur_bet_chips_  = 0;
	notify_bring_chips_ = false;
	//this->is_wait_ = true;
	this->game_step_=NONE_STEP;
	win_chips_ = 0;
	card_[0]= NULL;
	card_[1]= NULL;
}

int EnginePlayer::room_id(void)
{
	if(NULL!=this->monitor_)
	{
		return this->monitor_->room_id();
	}
	return -1;
}

int EnginePlayer::gate_id(void) const
{
	return this->gate_id_;
}

int EnginePlayer::table_id(void) const
{
	if(NULL!=this->cur_table_)
	{
		return this->cur_table_->table_id();
	}
	return 0;
}

int EnginePlayer::table_index(void) const
{
	return this->table_index_;
}

int EnginePlayer::seat(void)
{
	return this->table_index_+1;
}

void EnginePlayer::table_index(int index)
{
	//LockGuardReturn(RT_MUTEX,lock,this->rt_mutex_,;);
	this->table_index_ = index;
}

//const PlayerBaseInfo &EnginePlayer::base_info(void)
//{
//	return ;//this->base_info_;
//}

EngineMonitor *EnginePlayer::monitor(EngineMonitor *monitor)
{
	if(monitor!=NULL)
	{
		this->monitor_ = monitor;
	}
	return this->monitor_;
}

void EnginePlayer::save_data(void)
{
	LOG((INFO_LOG,"EnginePlayer::save_data[id:%d][account:%s][chips:%d]",this->role_id(),
			this->account().c_str(),this->chips_in_table_));

	if(this->chips_in_table_>0)
	{
		MySqlDB *globaldb = this->globaldb();
		bool g_save = false;
		if(globaldb!=NULL)
		{
			if(globaldb->giveback_chips(this->role_id(),this->chips_in_table_)<0)
			{
				LOG((ERROR_LOG,"EnginePlayer::save_data global [%s:%d] give back chips[%d]",
						this->account().c_str(),this->role_id(),chips_in_table_));
			}
			else
			{
				g_save = true;
			}
		}

		if(!g_save && this->monitor()->local_db()==NULL)
		{
			if(this->monitor()->local_db()->giveback_chips(
					this->role_id(),this->chips_in_table_)<0)
			{
				LOG((ERROR_LOG,"EnginePlayer::save_data local [%s:%d] give back chips[%d]",
						this->account().c_str(),this->role_id(),chips_in_table_));
			}
		}
		else if(!g_save)
		{
			LOG((ERROR_LOG,"EnginePlayer::save_data failed [id:%d][account:%s][chips:%d]",
					this->role_id(),this->account().c_str(),this->chips_in_table_));
		}
	}
}

int EnginePlayer::respond_success_to_client(int cmd,MessageBlock *mb)
{
	return this->monitor()->respond_to_gate(cmd,this->gate_id_,this->role_id(),0,mb);
}

int EnginePlayer::respond_error_to_client(int cmd,int err,MessageBlock *mb)
{
	return this->monitor()->respond_to_gate(cmd,this->gate_id_,this->role_id(),err,mb);
}

int EnginePlayer::enter_room(int gate,MessageBlock *mb)
{
	std::string account="",dbip="",dbname="",user="",pwd="";
	int sex=0,room=0,dbport = 0;
	*mb >> room >> account >> sex >>dbip >>dbport >>dbname >> user >> pwd;

	if(this->gate_id_==gate)
	{
		return 0;
	}
	this->gate_id_ = gate;
	this->set_baseinfo(this->role_id(),account,account,sex);
	this->db_info_.set(dbip,dbport,dbname,user,pwd);

	MySqlDB *globaldb = this->globaldb();
	if(NULL==globaldb )//|| ((result=conn->load_account_info(this))!=0))
	{
		LOG((ERROR_LOG,"EnginePlayer::enter_room->can't find db[%s:%d][roleid:%d]",
				dbip.c_str(),dbport,this->role_id()));
		return this->respond_error_to_client(INNER_E2G_ENTERROOM,ERROR_SERVER_PROBLEM);
	}

	if(this->monitor()->bind_player(this)!=0)
	{
		return this->respond_error_to_client(INNER_E2G_ENTERROOM,ERROR_SERVER_PROBLEM);
	}

	//this->notify_player_list();
	//conn->update_roomid(this);

	MessageBlock mb_send(8192);
	mb_send << globaldb->get_total_chips(this->role_id());
	this->monitor()->make_up_table_info(&mb_send);
	return this->respond_success_to_client(INNER_E2G_ENTERROOM,&mb_send);
}

int EnginePlayer::exit_room(int cmd,MessageBlock *mb)
{
	this->exit_table(NULL,false);

	int tmp_cmd = INNER_E2G_EXITROOM;
	if(cmd==CLIENT_LOG_OUT)
	{
		tmp_cmd = INNER_E2G_LOGOUT;
	}
	this->respond_success_to_client(tmp_cmd);
	return this->monitor()->unbind_player(this->role_id());
}

int EnginePlayer::enter_table(MessageBlock *mb)
{
	if(this->cur_table_!=NULL)
	{
		return 0;
	}
	int table_id = 0,pos =0;
	*mb >> table_id >> pos;

	if(this->monitor()->cfg()["auto_assign"].asInt()==1)
	{
		table_id = this->monitor()->assign_table()+1;
	}
	if(table_id<=0)
	{
		return this->respond_error_to_client(RETURN_ENTER_TABLE,ERROR_CLIENT_INFO);
	}

	Table *table =this->monitor()->find_table(table_id);
	if(NULL==table || table->is_full())
	{
		return this->respond_error_to_client(RETURN_ENTER_TABLE,ERROR_CLIENT_INFO);
	}

	int total_chips = this->total_chips();

	//检查玩家条件
	if(total_chips<table->min_chips())
	{
		return this->respond_error_to_client(RETURN_ENTER_TABLE,ERROR_LACK_CHIPS);
	}

	if(this->monitor()->cfg()["auto_assign"].asInt()==1)
	{
		pos = table->assign_pos()+1;
	}

	int result = table->player_enter(this,pos);
	if(result<0)
	{
		LOG((ERROR_LOG,"EnginePlayer::enter_table-->[role:%d][table:%d][seat:%d]",result,this->table_id(),pos-1));
		return this->respond_error_to_client(RETURN_ENTER_TABLE,result);
	}
	this->table_index_ = (pos-1);
	this->cur_table_ = table;

	LOG((INFO_LOG,"EnginePlayer::enter_table-->[role:%d][table:%d][seat:%d]",
			this->role_id(),this->table_id(),this->seat()));

	MessageBlock mb_send(4096);
	this->cur_table_->make_up_table_info(&mb_send,this->table_index(),true);
	this->respond_success_to_client(RETURN_ENTER_TABLE,&mb_send);
	this->notify_update_info(UPDATE_PLAYER_ENTER);
	return this->notify_operation(0);
}

int EnginePlayer::exit_table(MessageBlock *mb,bool notify)
{
	if(NULL==this->cur_table_)
	{
		if(notify==false)
		{
			return 0;
		}
		return this->respond_error_to_client(RETURN_EXIT_TABLE,ERROR_CLIENT_INFO);
	}
	LOG((INFO_LOG,"EnginePlayer::exit_table-->[%d][%d]",this->table_id(),this->seat()));

	this->cur_table_->player_exit(this);

	this->notify_update_info(UPDATE_PLAYER_EXIT);
	if (this->is_in_game())// || this->is_fold())
	{
		//this->base_info_.total_chips -=this->cur_bet_chips_;
		this->chips_serial_record(RECORD_GAME_LOST,-this->cur_bet_chips_);
	}

	this->save_data();
	this->exit_table_reset();
	this->respond_success_to_client(RETURN_EXIT_TABLE);

	if(notify)
	{
		int total_chips = this->total_chips();
		MessageBlock mb_send(8192);
		mb_send <<  total_chips;
		this->monitor()->make_up_table_info(&mb_send);
		this->respond_success_to_client(RETURN_ENTER_ROOM,&mb_send);
	}
	return 0;
}

int EnginePlayer::start_game(MessageBlock *mb)
{
	if(this->is_in_game() || this->is_ready())
	{
		return 0;
	}

	if(NULL==this->cur_table_ || this->chips_in_table_<=this->cur_table_->base_info().cost)
	{
		return this->respond_error_to_client(RETURN_START_GAME,ERROR_CLIENT_INFO);
	}
	this->cur_table_->player_start(this);
	this->notify_start_ = false;
	this->set_game_status(GAME_STATUS_PREPARE);
	this->notify_update_info(UPDATE_GAME_STATUS);
	return this->respond_success_to_client(RETURN_START_GAME);
}

//下注
int EnginePlayer::bet(MessageBlock *mb)
{
	if(!this->operation_.bet)
	{
		return this->respond_error_to_client(RETURN_BET,ERROR_CLIENT_INFO);
	}
	this->operation_.reset();

	int amount =0;
	*mb >> amount;
	if(amount<=0 || NULL==this->cur_table_|| this->chips_in_table_<=0)
	{
		return this->respond_error_to_client(RETURN_BET,ERROR_CLIENT_INFO);
	}

	if(this->cur_table_->is_calculating())
	{
		LOG((ERROR_LOG,"EnginePlayer::bet==calculating[%s][%d]===",
				this->cur_table_->name().c_str(),this->role_id()));
		return 0;
	}

	if(amount>=this->chips_in_table_)
	{
		this->all_in();
	}
	else
	{
		LockGuardReturn(RT_MUTEX,lock,this->rt_mutex_,0);
		this->cur_bet_chips_+=amount;
		this->chips_in_table_ -=amount;
		this->cur_table_->bet(this);
		this->notify_update_info(UPDATE_CHIPS);
		this->broadcast_operation(NOTIFY_BET,amount);
	}
	return this->respond_success_to_client(RETURN_BET);
}

//加赌注
int EnginePlayer::raise(MessageBlock *mb)
{
	if(!this->operation_.raise)
	{
		return this->respond_error_to_client(RETURN_BET,ERROR_CLIENT_INFO);
	}
	this->operation_.reset();

	int amount =0;
	*mb >> amount;
	if(amount<=0 ||NULL==this->cur_table_ || this->chips_in_table_<=0)
	{
		return this->respond_error_to_client(RETURN_RAISE,ERROR_CLIENT_INFO);
	}

	if(this->cur_table_->is_calculating())
	{
		LOG((ERROR_LOG,"EnginePlayer::raise==calculating[%s][%d]===",
					this->cur_table_->name().c_str(),this->role_id()));
		return 0;
	}

	if(amount>=this->chips_in_table_)
	{
		this->all_in();
	}
	else
	{
		this->cur_bet_chips_+=amount;
		this->chips_in_table_ -=amount;
		this->cur_table_->raise(this);
		this->notify_update_info(UPDATE_CHIPS);
		this->broadcast_operation(NOTIFY_RAISE,amount);
	}
	return this->respond_success_to_client(RETURN_RAISE);
}

//全下
int EnginePlayer::all_in(MessageBlock *mb)
{
	if(!this->operation_.all_in)
	{
		return this->respond_error_to_client(RETURN_BET,ERROR_CLIENT_INFO);
	}
	this->operation_.reset();

	if(NULL==this->cur_table_)
	{
		return this->respond_error_to_client(RETURN_ALL_IN,ERROR_CLIENT_INFO);
	}

	if(this->cur_table_->is_calculating())
	{
		LOG((ERROR_LOG,"EnginePlayer::all_in==calculating[%s][%d]===",
						this->cur_table_->name().c_str(),this->role_id()));
		return 0;
	}

	this->set_game_status(GAME_STATUS_ALL_IN);
	{
		LockGuardReturn(RT_MUTEX, lock, this->rt_mutex_, 0);
		this->cur_bet_chips_ += this->chips_in_table_;
		this->chips_in_table_ = 0;
		this->cur_table_->all_in(this);
	}
	this->notify_update_info(UPDATE_CHIPS);
	this->notify_update_info(UPDATE_GAME_STATUS);
	this->broadcast_operation(NOTIFY_ALLIN,UPDATE_GAME_STATUS);
	return this->respond_success_to_client(RETURN_ALL_IN);
}

//弃牌
int EnginePlayer::fold(MessageBlock *mb,bool force)
{
	if(!this->operation_.fold && !force)
	{
		return this->respond_error_to_client(RETURN_BET,ERROR_CLIENT_INFO);
	}
	this->operation_.reset();

	if(NULL==this->cur_table_)
	{
		return this->respond_error_to_client(RETURN_FOLD,ERROR_CLIENT_INFO);
	}

	if(this->cur_table_->is_calculating())
	{
		LOG((ERROR_LOG,"EnginePlayer::fold==calculating[%s][%d]===",
								this->cur_table_->name().c_str(),this->role_id()));
		return 0;
	}

	if(cur_bet_chips_>0)
	{
		//this->chips_in_table_ -=cur_bet_chips_;
		//this->base_info_.total_chips -=cur_bet_chips_;
		//this->save_data();
		this->chips_serial_record(RECORD_GAME_LOST,-cur_bet_chips_);
	}
	this->stop_game_reset();
	this->set_game_status(GAME_STATUS_FOLD);
	this->cur_table_->fold(this,force);
	this->notify_update_info(UPDATE_GAME_STATUS);
	this->broadcast_operation(NOTIFY_FOLD,GAME_STATUS_FOLD);
	return this->respond_success_to_client(RETURN_FOLD);
}

//跟牌
int EnginePlayer::call(MessageBlock *mb)
{
	if(!this->operation_.call)
	{
		return this->respond_error_to_client(RETURN_BET,ERROR_CLIENT_INFO);
	}
	this->operation_.reset();

	if(NULL==this->cur_table_)
	{
		return this->respond_error_to_client(RETURN_CALL,ERROR_CLIENT_INFO);
	}

	if(this->cur_table_->is_calculating())
	{
		LOG((ERROR_LOG,"EnginePlayer::call==calculating[%s][%d]===",
				this->cur_table_->name().c_str(),this->role_id()));
		return 0;
	}

	if(this->chips_in_table_+this->cur_bet_chips_<this->cur_table_->cur_max_bet())
	{
		return this->respond_error_to_client(RETURN_CALL,ERROR_CLIENT_INFO);
	}

	this->chips_in_table_ -= (this->cur_table_->cur_max_bet()-this->cur_bet_chips_);
	this->cur_bet_chips_= this->cur_table_->cur_max_bet();

	if(this->chips_in_table_<=0)
	{
		this->all_in();
	}
	else
	{
		this->cur_table_->call(this);
		this->notify_update_info(UPDATE_CHIPS);
		this->broadcast_operation(NOTIFY_CALL);
	}
	return this->respond_success_to_client(RETURN_CALL);
}

//过牌
int EnginePlayer::check(MessageBlock *mb)
{
	if(!this->operation_.check)
	{
		return this->respond_error_to_client(RETURN_BET,ERROR_CLIENT_INFO);
	}
	this->operation_.reset();

	if(NULL==this->cur_table_ || this->cur_bet_chips_<this->cur_table_->cur_max_bet())
	{
		return this->respond_error_to_client(RETURN_CHECK,ERROR_CLIENT_INFO);
	}
	if(this->cur_table_->is_calculating())
	{
		LOG((ERROR_LOG,"EnginePlayer::check==calculating[%s][%d]===",
						this->cur_table_->name().c_str(),this->role_id()));
		return 0;
	}

	this->cur_table_->check(this);
	return this->respond_success_to_client(RETURN_CHECK);
}

//带入筹码/修改带入筹码
int EnginePlayer::modify_chips(MessageBlock *mb)
{
	//游戏进行中不能带入筹码
	if(this->is_in_game() )//&& this->cur_table_->is_calculating())
	{
		LOG((INFO_LOG,"EnginePlayer::modify_chips error[roleid:%d]",this->role_id()));
		return 0;
	}

	int amount =0;
	if(NULL!=mb)
	{
		*mb >> amount >> this->auto_bring_in_;
	}
	else if(this->auto_bring_in_==true)
	{
		amount = this->last_bring_chips_;
	}
	else
	{
		return -1;
	}

	MySqlDB *globaldb = this->globaldb();
	if(NULL==globaldb)
	{
		return this->respond_error_to_client(RETURN_MODIFY_CHIPS,ERROR_SERVER_PROBLEM);
	}

	if(amount >this->cur_table_->base_info().max_chips_
			|| amount>this->total_chips())
	{
		return this->respond_error_to_client(RETURN_MODIFY_CHIPS,ERROR_CLIENT_INFO);
	}

	int result = globaldb->borrow_chips(this->role_id(),amount);
	if(result < 0)
	{
		return this->respond_error_to_client(RETURN_MODIFY_CHIPS,result);
	}

	LOG((INFO_LOG,"EnginePlayer::modify_chips [%s:%d]borrow chips[%d]",
			this->account().c_str(),this->role_id(),amount));

	this->chips_serial_record(RECORD_BORROW,amount);
	this->chips_in_table_ +=amount;
	this->last_bring_chips_ = amount;
	this->notify_update_info(UPDATE_CHIPS);
	if(NULL!=mb)
	{//just for refresh timer
		this->cur_table_->check(this);
	}
	return this->respond_success_to_client(RETURN_MODIFY_CHIPS);
}

void EnginePlayer::sub_cost(RecordChips type,int cost)
{
	this->chips_in_table_ -=cost;
	this->chips_in_table_ = (this->chips_in_table_ <0)?0:this->chips_in_table_;
	//this->base_info_.total_chips -=cost;
	this->chips_serial_record(type,-cost);
}

int EnginePlayer::notify_operation(int max_bet)
{
	if(max_bet==0)
	{
		this->modify_chips();//check if auto bring in
	}

	this->operation_.reset();
	MessageBlock mb(sizeof(int)*10);
	if(this->chips_in_table_<=this->cur_table_->base_info().cost)
	{//通知带入筹码
		if(this->notify_bring_chips_ == true)
		{
			return 0;
		}
		this->operation_.bring_chips = true;
		this->notify_bring_chips_ = true;
	}
	else if (!(this->is_ready() || this->is_in_game()))
	{
		if(this->notify_start_ == true)
		{
			return 0;
		}
		this->notify_start_ = true;
		this->operation_.start = true;
	}
	else
	{
		if((this->chips_in_table_+this->cur_bet_chips_)>max_bet)
		{
			this->operation_.bet = true;
		}
		if((this->chips_in_table_+this->cur_bet_chips_)>max_bet)
		{
			this->operation_.bet = true;
		}
		if(this->cur_bet_chips_<max_bet
				&& (this->chips_in_table_+this->cur_bet_chips_)>max_bet)
		{
			this->operation_.call = true;
		}
		if(this->cur_bet_chips_>=max_bet)
		{
			this->operation_.check = true;
		}
		if(this->chips_in_table_>0)
		{
			this->operation_.all_in = true;
		}
		if(this->game_status_==GAME_STATUS_START)
		{
			this->operation_.fold = true;
		}
	}
	mb << this->operation_.bring_chips;
	if(this->operation_.bring_chips)
	{
		mb<< this->cur_table_->min_chips();
	}

	mb << this->operation_.start;
	mb << this->operation_.bet ;

	if(this->operation_.bet )
	{
		mb<< (max_bet-this->cur_bet_chips_)+1;
	}
	mb << this->operation_.call << this->operation_.check
	   << this->operation_.all_in << this->operation_.fold;
	return this->respond_success_to_client(STC_NOTIFY_OPERATE,&mb);
}

bool EnginePlayer::is_all_in(void)
{
	return (this->game_status_==GAME_STATUS_ALL_IN);
}

bool EnginePlayer::is_fold(void)
{
	return (this->game_status_==GAME_STATUS_FOLD);
}

bool EnginePlayer::is_in_game(void)
{
	return (this->is_gaming() || this->is_all_in());
}

bool EnginePlayer::is_gaming(void)
{
	return (this->game_status_==GAME_STATUS_START);
}

//是否已准备开始游戏
bool EnginePlayer::is_ready(void)
{
	return (this->game_status_==GAME_STATUS_PREPARE);
}

void EnginePlayer::set_game_status(GameStatus status)
{
	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex_,;);
	this->game_status_ = status;
}

int EnginePlayer::notify_player_list(void)
{
	MessageBlock mb(2048);

	mb << this->monitor()->room_id();

	if(this->monitor()->make_up_player_info(&mb)!=0)
	{
		return -1;
	}
	return this->monitor()->broadcast_to_room(STC_PLAYER_LIST,&mb);
}

int EnginePlayer::broadcast_operation(int type,int num)
{
	MessageBlock mb(sizeof(int)*10);
	mb << type;
	switch (type)
	{
		case NOTIFY_BET:
		case NOTIFY_RAISE:
		{
			mb << num;//num is chips
			break;
		}
		case NOTIFY_FOLD:
		case NOTIFY_ALLIN:
		{
			mb << num; //num is status
			break;
		}
		case NOTIFY_CHECK:
		case NOTIFY_CALL:
		{
			mb << 0;
			break;
		}
		default:
			return -1;
	}
	return this->notify_update_info(UPDATE_OPERATION,&mb);
}

int EnginePlayer::notify_update_info(int type,MessageBlock *mb)
{
	MessageBlock mb_send(2048);
	mb_send << this->table_id()<< this->role_id()
			<< this->seat() << type;

	bool to_self = false;
	bool to_room = false;
	switch(type)
	{
		case UPDATE_GAME_STATUS:
		{
			to_self = true;
			if(this->game_status_==GAME_STATUS_PREPARE
					|| this->game_status_==GAME_STATUS_START)
			{
				to_room = true;
			}
			mb_send << this->game_status_;
			break;
		}
		case UPDATE_CHIPS:
		{
			to_self = true;
			mb_send << this->chips_in_table_ << this->cur_bet_chips_
					<< this->total_chips();
			break;
		}
		case UPDATE_PLAYER_ENTER:
		case UPDATE_PLAYER_EXIT:
		{
			to_room = true;
			mb_send << this->account();
			break;
		}
		case UPDATE_CLEAN:
		{
			return this->respond_success_to_client(STC_BROADCAST_TABLE_INFO,&mb_send);
		}
		case UPDATE_OPERATION:
		{
			to_self = true;
			break;
		}
		default:
			return -1;
	}
	if(NULL!=mb)
	{
		mb_send.write(mb->rd_ptr(),mb->data_len());
	}

	if(to_room)
	{
		return this->monitor()->broadcast_to_room(STC_BROADCAST_TABLE_INFO,&mb_send);
	}

	return this->cur_table_->broadcast_to_table(STC_BROADCAST_TABLE_INFO,
				&mb_send,this->role_id(),to_self);
}

void EnginePlayer::chips_serial_record(RecordChips type,int amount)
{
	ChipsRecord record;
	record.amount = amount;
	record.cur_bet = this->cur_bet_chips_;
	record.type = type;
	record.role_id = this->role_id();
	record.account = this->account();
	record.room = this->monitor_->room_id();
	record.table = this->table_id();
	record.table_index = this->seat();
	record.total_chips = this->chips_in_table_;
	record.time = TimeValue::now_time_str_sec();

	MySqlDB *globaldb = this->globaldb();
	if(globaldb!=NULL)
	{
		globaldb->save_chips_record(&record);
	}
	else if(this->monitor()->local_db()!=NULL)
	{
		this->monitor()->local_db()->save_chips_record(&record);
	}

	LOG((INFO_LOG,"chips_log:[%d:%s:%s:%d:%d:%d:%d:%d:%d:%d]",
				record.role_id,record.account.c_str(),record.time.c_str(),
				record.type,record.amount,record.total_chips,record.cur_bet,
				record.room,record.table,record.table_index));

}

void EnginePlayer::game_end(void)
{
	this->chips_in_table_ +=this->win_chips_;
	int chips = this->win_chips_-this->cur_bet_chips_;
	this->set_game_status(GAME_STATUS_STOP);
	//this->base_info_.total_chips +=chips;
	this->notify_update_info(UPDATE_CHIPS);

	if(chips<0)
	{
		this->chips_serial_record(RECORD_GAME_LOST,chips);
	}
	else if(chips>0)
	{
		this->chips_serial_record(RECORD_GAME_WIN,chips);
	}
	this->stop_game_reset();
}

int EnginePlayer::total_chips(void)
{
	MySqlDB *globaldb = this->globaldb();
	if (NULL == globaldb)
	{
		return 0;
	}
	return globaldb->get_total_chips(this->role_id());
}
